package com.xiaoshuidi.cloud.module.rooms.job.xxljob;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.xiaoshuidi.cloud.framework.common.exception.ServiceException;
import com.xiaoshuidi.cloud.framework.filings.config.FilingsProperties;
import com.xiaoshuidi.cloud.framework.filings.core.FilingsApi;
import com.xiaoshuidi.cloud.framework.filings.core.enums.HouseResouseTypeEnum;
import com.xiaoshuidi.cloud.framework.filings.core.enums.UriEnum;
import com.xiaoshuidi.cloud.framework.filings.core.service.dto.*;
import com.xiaoshuidi.cloud.framework.tenant.core.job.TenantJob;
import com.xiaoshuidi.cloud.module.rooms.controller.admin.roomel.vo.RoomelUpdateReqVO;
import com.xiaoshuidi.cloud.module.rooms.enums.ErrorCodeConstants;
import com.xiaoshuidi.cloud.module.rooms.enums.RoomHouseFilingsStatus;
import com.xiaoshuidi.cloud.module.rooms.mq.producer.RoomEsProducer;
import com.xiaoshuidi.cloud.module.rooms.pojo.RoomHouseFilings;
import com.xiaoshuidi.cloud.module.rooms.pojo.RoomHouseFilingsLogs;
import com.xiaoshuidi.cloud.module.rooms.pojo.dto.roomhouse.RoomHouseFilingsListDTO;
import com.xiaoshuidi.cloud.module.rooms.repository.RoomHouseFilingsLogsRepository;
import com.xiaoshuidi.cloud.module.rooms.repository.RoomHouseFilingsRepository;
import com.xiaoshuidi.cloud.module.rooms.repository.RoomHouseRepository;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 房源备案跑批
 *
 * @Author Feng
 * @date 2023/5/15
 */
@Component
@Slf4j
@TenantJob
@RequiredArgsConstructor
public class ConcentratedFilingsJob {

    private final FilingsApi<EnterpriseHousingInquiryResp, EnterpriseHousingInquiryBo> filingsApi;
    private final RoomHouseRepository roomHouseRepository;
    private final FilingsApi<InventoryCheckResp, CentralizeHouseCheckBo> centralizeHouseCheckFilingsApi;
    private final FilingsProperties filingsProperties;
    private final RoomHouseFilingsRepository filingsRepository;
    private final RoomHouseFilingsLogsRepository filingsLogsRepository;
    private final RoomEsProducer roomEsProducer;

    /**
     * 集中式房源数据跑批备案 默认30天内创建或修改的房源
     */
    @XxlJob("room-concentrated-filings-job")
    public void execute(Integer days) {
        //获取备案平台所有房源信息
        int limit = 100;
        int page = 1;
        EnterpriseHousingInquiryBo bo = new EnterpriseHousingInquiryBo();
        bo.setLimit(limit);
        bo.setPage(page);
        bo.setSecretKey(filingsProperties.getSecretKey());
        bo.setType(HouseResouseTypeEnum.CONCENTRATE.getCode());
        CommonFilingsResponse<EnterpriseHousingInquiryResp> response = filingsApi.execute(bo, UriEnum.QUERY_HOUSE, EnterpriseHousingInquiryResp.class);
        if (!response.getStatus()) {
            log.error("获取房源备案信息错误: {}", response.getMsg());
            throw new ServiceException(ErrorCodeConstants.HOUSE_FILINGS_ERROR.getCode(), ErrorCodeConstants.HOUSE_FILINGS_ERROR.getMsg() + response.getMsg());
        }
        EnterpriseHousingInquiryResp data = response.getData();
        if (days == null || days <= 0) {
            days = 30;
        }
        LocalDateTime startTime = LocalDateTime.of(LocalDate.now().minusDays(days), LocalTime.MIN);
        List<RoomHouseFilingsListDTO> dtos = roomHouseRepository.filingsHouseList(startTime, null);
        Map<String, RoomHouseFilingsListDTO> map = new HashMap<>();
        dtos.forEach(s -> {
            String joinNo = joinNo(s.getArea(), s.getBuildingNo(), s.getHouseNo());
            map.put(joinNo, s);
        });
        process(data, map);
        Integer count = data.getCount();
        int totalPage = count / limit;
        if (count % limit != 0) {
            totalPage++;
        }
        page++;
        //分页获取
        for (int i = page; i <= totalPage; i++) {
            bo.setPage(page);
            response = filingsApi.execute(bo, UriEnum.QUERY_HOUSE, EnterpriseHousingInquiryResp.class);
            if (!response.getStatus()) {
                log.error("获取房源备案信息错误: {}", response.getMsg());
                continue;
            }
            process(data, map);
        }
    }

    /**
     * 处理备案数据
     *
     * @param resp
     */
    private void process(EnterpriseHousingInquiryResp resp, Map<String, RoomHouseFilingsListDTO> map) {
        List<EnterpriseHousingInquiryResp.RespData> data = resp.getData();
        List<RoomHouseFilings> saveFilingsList = new ArrayList<>();
        List<RoomHouseFilings> updateFilingsList = new ArrayList<>();
        List<RoomHouseFilingsLogs> logsList = new ArrayList<>();
        List<RoomelUpdateReqVO> roomEsVoList = new ArrayList<>();
        for (EnterpriseHousingInquiryResp.RespData respData : data) {
            String joinNo = joinNo(respData.getHouseArea(), respData.getBuildNo(), respData.getRoomNo());
            RoomHouseFilingsListDTO dto = map.get(joinNo);
            if (dto == null) {
                continue;
            }
            //调用租赁平台 集中式房源校验
            CentralizeHouseCheckBo bo = new CentralizeHouseCheckBo();
            bo.setHouseId(respData.getHouseId())
                    .setUniqueDataId(String.valueOf(dto.getHouseId()))
                    .setSecretKey(filingsProperties.getSecretKey());

            CommonFilingsResponse<InventoryCheckResp> response = centralizeHouseCheckFilingsApi.execute(bo, UriEnum.CENTRALIZE_HOUSE_CHECK, InventoryCheckResp.class);
            RoomHouseFilings roomHouseFilings = new RoomHouseFilings();
            roomHouseFilings.setId(dto.getFilingsId())
                    .setRoomHouseId(dto.getHouseId())
                    .setExternalHouseId(respData.getHouseId());
            if (response.getStatus()) {
                roomHouseFilings.setStatus(RoomHouseFilingsStatus.SUCCESS.getCode())
                        .setCheckCode(response.getData().getCheckCode())
                        .setCheckCodeInDate(response.getData().getCheckCodeIndate());
                RoomelUpdateReqVO roomelUpdateReqVO = new RoomelUpdateReqVO();
                roomelUpdateReqVO.setId(dto.getHouseId())
                        .setCheckCode(response.getData().getCheckCode());
                roomEsVoList.add(roomelUpdateReqVO);
            } else {
                roomHouseFilings.setStatus(RoomHouseFilingsStatus.ERROR.getCode());
            }
            if (roomHouseFilings.getId() == null) {
                saveFilingsList.add(roomHouseFilings);
            } else {
                updateFilingsList.add(roomHouseFilings);
            }
            //插入日志
            RoomHouseFilingsLogs logs = new RoomHouseFilingsLogs();
            logs.setRoomHouseId(dto.getHouseId())
                    .setUrl(UriEnum.INVENTORY_CHECK_URI.getUri())
                    .setStatus(response.getStatus().toString())
                    .setSendJson(JSONObject.toJSONString(bo))
                    .setReceiveJson(JSONObject.toJSONString(response))
                    .setErrMsg(response.getMsg())
                    .setTenantId(dto.getTenantId());
            logsList.add(logs);
        }
        if (CollectionUtil.isNotEmpty(saveFilingsList)) {
            filingsRepository.saveBatch(saveFilingsList);
        }
        if (CollectionUtil.isNotEmpty(updateFilingsList)) {
            filingsRepository.updateBatchById(updateFilingsList);
        }
        if (CollectionUtil.isNotEmpty(logsList)) {
            filingsLogsRepository.saveBatch(logsList);
        }
        if (CollectionUtil.isNotEmpty(roomEsVoList)) {
            roomEsProducer.updateBatchRoomEl(roomEsVoList);
        }
    }

    private String joinNo(String area, String buildingNo, String houseNo) {
        return String.format("%s-%s-%s", area, buildingNo, houseNo);
    }

}
